#include"process_pool.h"

int main(int argc,char** argv)
{
    if(argc!=4)
    {
        printf("./process_poll_server IP PORT PROCESS_NUM\n");
        return -1;
    }
    int process_num=atoi(argv[3]);//子进程数目
    //p_manage用来管理所有的子进程信息
    process_data_t *p_manage=(process_data_t*)calloc(process_num,sizeof(process_data_t));//申请子进程数目相等的结构体空间
    make_child(p_manage,process_num);//创建process_num个子进程
    int socket_fd;
    tcp_init(&socket_fd,argv[1],argv[2]);//初始化一个tcp
    printf("socket_fd=%d\n",socket_fd);
    //初始化epoll，父进程既要监控socket_fd,又要监控没一个子进程的管道对端
    int epfd=epoll_create(1);//初始化一个epfd
    int ret=epoll_add(epfd,socket_fd);//注册socket_fd，监控socket_fd
    SELFFUNC_ERR_CHECK(ret,"epoll_add");
    int i;
    for(i=0;i<process_num;i++)
    {
        ret=epoll_add(epfd,p_manage[i].fd);//注册每一个子进程的管道对端
        SELFFUNC_ERR_CHECK(ret,"epoll_add");
    }

    int new_fd,j;
    int ready_fd_num;//就绪描述符的数量
    char flag;
    struct epoll_event *evs=(struct epoll_event *)calloc(process_num+1,sizeof(struct epoll_event));
    struct sockaddr_in client_addr;
    while(1)
    {
        ready_fd_num=epoll_wait(epfd,evs,process_num+1,-1);
        for(i=0;i<ready_fd_num;i++)
        {
            if(evs[i].data.fd==socket_fd)//如果有客户端连接了
            {
                bzero(&client_addr,sizeof(client_addr));
                socklen_t addr_len=sizeof(client_addr);
                new_fd=accept(socket_fd,(struct sockaddr*)&client_addr,&addr_len);//accept接收，获得nwe_fd
                printf("%s %d is connect\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
                for(j=0;j<process_num;j++)//找到非忙碌子进程
                {
                    if(0==p_manage[j].busy)
                    {
                        send_fd(p_manage[i].fd,new_fd);//任务派发给子进程
                        p_manage[i].busy=1;//设置对应的子进程，变为忙碌状态
                        printf("child %d is busy\n",p_manage[j].pid);
                        break;
                    }
                }
                close(new_fd);//无论是否找到空闲子进程，都关闭new_fd
            }
            for(j=0;j<process_num;j++)
            {
                if(evs[j].data.fd==p_manage[j].fd)//如果收到子进程空闲的通知
                {
                    read(p_manage[j].fd,&flag,sizeof(flag));//把内容读出来，避免一直可读
                    p_manage[j].busy=0;//设置为非忙碌
                    printf("child %d is not busy\n",p_manage[j].pid);
                    break;
                }
            }
        }
    }
    return 0;
}